package com.songshuai.webapi.crm.service.impl;

import com.songshuai.webapi.baseapi.dto.LoginUserDto;
import com.songshuai.webapi.baseapi.dto.feign.response.MasterSourceItemDto;
import com.songshuai.webapi.baseapi.enumerations.*;
import com.songshuai.webapi.baseapi.enumerations.crm.*;
import com.songshuai.webapi.baseapi.exception.BusinessException;
import com.songshuai.webapi.baseapi.pojo.QueryResponse;
import com.songshuai.webapi.baseapi.dto.feign.response.AccountInfoListResDto;
import com.songshuai.webapi.baseapi.pojo.feign.request.MasterNumberParamReqDto;
import com.songshuai.webapi.baseapi.utils.*;
import com.songshuai.webapi.crm.constant.CrmConstant;
import com.songshuai.webapi.crm.dao.CommunicateRecordMapper;
import com.songshuai.webapi.crm.dao.CustomInfoMapper;
import com.songshuai.webapi.crm.dao.PageListColumnsConfigMapper;
import com.songshuai.webapi.crm.dto.request.customer.AddCustomerInfoReqDto;
import com.songshuai.webapi.crm.dto.request.customer.AddPageListColumnsConfigReqDto;
import com.songshuai.webapi.crm.dto.request.customer.CustomerListReqDto;
import com.songshuai.webapi.crm.dto.response.customer.CommunicateRecordListResDto;
import com.songshuai.webapi.crm.dto.response.customer.CustomerExportDto;
import com.songshuai.webapi.crm.dto.response.customer.CustomerListResDto;
import com.songshuai.webapi.crm.enumerations.error.BaseError;
import com.songshuai.webapi.crm.enumerations.error.CustomerError;
import com.songshuai.webapi.crm.model.CustomInfo;
import com.songshuai.webapi.crm.model.PageListColumnsConfig;
import com.songshuai.webapi.crm.service.CustomerService;
import com.songshuai.webapi.crm.util.ExcelUtil;
import com.songshuai.webapi.crm.util.Util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author:wbl
 * @Date: 2018/12/28
 */
@Service
@Slf4j
public class CustomerServiceImpl extends BaseServiceImpl implements CustomerService {

    @Autowired
    private CustomInfoMapper customInfoMapper;

    @Autowired
    private CommunicateRecordMapper communicateRecordMapper;

    @Autowired
    private PageListColumnsConfigMapper pageListColumnsConfigMapper;

    @Autowired
    private SnowFlakeUtil snowFlakeUtil;

    @Autowired
    private OssUploadUtil uploadUtil;

    @Value("${file.excelPath}")
    private String excelPath;

    @Value("${file.clueExportFileName}")
    private String clueExportFileName;

    //新增潜在学员
    public boolean addCustomer(AddCustomerInfoReqDto parmDto){
        LoginUserDto loginUser = getCurrentUser();
        //未登录
        if(loginUser == null){
            throw new BusinessException(BaseError.ERROR_NO_LOGIN.getMsg(), ResultStatus.FAILOfficial);
        }
        //校验手机号格式
        if(!RegexUtil.isMobile(parmDto.getPhone())){
            throw new BusinessException(CustomerError.ERROR_MOBILE_FORMAT.getMsg(), ResultStatus.FAILOfficial);
        }
        //校验当前校区手机号唯一
        if(loginUser.getCampusId() == null){
            throw new BusinessException(BaseError.ERROR_NO_CAMPUS.getMsg(), ResultStatus.FAILOfficial);
        }
        //校验备用手机号格式
        if(StringUtils.isNotBlank(parmDto.getPhoneBackup())){
            //当备用手机号不为空
            if(!RegexUtil.isMobile(parmDto.getPhoneBackup())){
                throw new BusinessException(CustomerError.ERROR_MOBILE_FORMAT.getMsg(), ResultStatus.FAILOfficial);
            }
        }
        CustomInfo customInfoCheck = customInfoMapper.queryCustomByMobile(loginUser.getCampusId(),parmDto.getPhone());
        if(customInfoCheck != null){
            throw new BusinessException(CustomerError.ERROR_MOBILE_IS_EXITS.getMsg(), ResultStatus.FAILOfficial);
        }
        CustomInfo customInfo = new CustomInfo();
        PropertiesUtil.copyProperties(parmDto, customInfo);
        customInfo.setCustomId(snowFlakeUtil.nextId());
        customInfo.setCreateBy(loginUser.getId());
        customInfo.setCreateTime(new Date());
        customInfo.setUpdateBy(loginUser.getId());
        customInfo.setUpdateTime(new Date());
        //默认学员类型：潜在学员
        customInfo.setCustomType(CustomType.ONE.getCode());
        //默认所属人：当前登录人
        customInfo.setOwner(loginUser.getId());
        //默认跟进状态：待跟进
        customInfo.setFollowStatus(FollowStatusEnum.WaitFollow.getCode());
        //默认有效来源：首次来源
        customInfo.setEffectSource(parmDto.getFirstSource());
        //校区
        customInfo.setCampusId(loginUser.getCampusId());
        //学员编号
        MasterNumberParamReqDto paramReqDto = new MasterNumberParamReqDto();
        paramReqDto.setLoginId(loginUser.getId());
        paramReqDto.setNumberKey(CrmConstant.CUSTOME_NO_SIGN);
        paramReqDto.setNumberType(AutoGenericUtil.autoGenericCode(loginUser.getCampusId(),5));
        String customNo = schoolMasterNumberClient.queryNumberValueByParam(/*getBearerToken(),*/paramReqDto).getData();
        customInfo.setCustomNo(customNo);
        return customInfoMapper.addCustomer(customInfo) > 0;
    };

    @Override
    public List<CustomerListResDto> queryCustomerInfoListByParam(CustomerListReqDto reqDto){
        //查询符合条件的学员信息
        List<CustomInfo> customInfoList = customInfoMapper.queryCustomerInfoListByParam(reqDto);
        if(CollectionUtils.isNotEmpty(customInfoList)) {
            //最后跟进内容id集合
            Map<String,String> recordMap = new HashMap<>();
            List<CommunicateRecordListResDto> recordList = new ArrayList<>();
            List<String> lastCommunicateIdList = customInfoList.stream().filter(f -> f.getLastcommunicateId() != null)
                    .map(x -> x.getLastcommunicateId()).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(lastCommunicateIdList)){
                recordList = communicateRecordMapper.queryCommunicateRecordListByIds(lastCommunicateIdList);
            }
            //跟进内容：list转map
            for(CommunicateRecordListResDto resDto : recordList){
                recordMap.put(resDto.getCommunicateId(),resDto.getCommunicateContent());
            }
            //跟进人id集合
            Map<Integer,String> userMap = new HashMap<>();
            List<AccountInfoListResDto> userList = new ArrayList<>();
            List<Integer> userIdList = customInfoList.stream().filter(f -> f.getOwner() != null)
                    .map(x -> x.getOwner()).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(userIdList)) {
                QueryResponse<List<AccountInfoListResDto>> userResponse = permissionClient.queryUserInfoByIds(getBearerToken(),userIdList);
                userList = userResponse.getData();
            }
            //跟进人：list转map
            for(AccountInfoListResDto resDto : userList){
                userMap.put(resDto.getId(),resDto.getTrueName());
            }
            //类转换
            List<CustomerListResDto> resDtoList = customInfoList.stream().map(customInfo -> {
                CustomerListResDto resDto = new CustomerListResDto();
                PropertiesUtil.copyProperties(customInfo, resDto);
                if(customInfo.getLastCommunicateTime() != null) {
                    //最后一次跟进
                    if (recordMap.get(customInfo.getLastcommunicateId()) != null) {
                        resDto.setLastCommunicate(Util.ChangeDateToString(customInfo.getLastCommunicateTime(), DateUtil.dateFormat) + ":" + recordMap.get(customInfo.getLastcommunicateId()));
                    } else {
                        resDto.setLastCommunicate(Util.ChangeDateToString(customInfo.getLastCommunicateTime(), DateUtil.dateFormat) + ":");
                    }
                }
                if(customInfo.getEffectSource() != null) {
                    //来源名称
                    List<MasterSourceItemDto> sourceList = schoolMasterSourceClient.queryMasterSourceList().getData();
                    if (sourceList != null) {
                        for (MasterSourceItemDto dto : sourceList) {
                            if (customInfo.getEffectSource().equals(dto.getSourceId())) {
                                resDto.setSourceName(dto.getChannelName());
                            }
                        }
                    }
                }
                //跟进人名称
                resDto.setOwnerName(userMap.get(customInfo.getOwner()));
                //跟进状态名称
                resDto.setFollowStatusName(FollowStatusEnum.getMsg(customInfo.getFollowStatus()));
                //阶段年级名称
                String stageName = StepEnum.getMsg(customInfo.getStage());
                String grageName = GradeEnum.getMsg(customInfo.getGrade());
                String stageGradeName = "";
                if(StringUtils.isNotBlank(stageName)){
                    stageGradeName = stageName;
                }
                if(StringUtils.isNotBlank(grageName)){
                    stageGradeName = stageGradeName + grageName;
                }
                resDto.setStageGradeName(stageGradeName);
                //意向名称
                resDto.setIntendName(CustomIntendEnum.getMsg(customInfo.getIntend()));
                return resDto;
            }).collect(Collectors.toList());
            return resDtoList;
        }
        return null;
    }

    //今日待跟进总计
    @Override
    public Integer queryFollowCustomerCount(){
        LoginUserDto loginUser = getCurrentUser();
        //未登录
        if(loginUser == null){
            throw new BusinessException(BaseError.ERROR_NO_LOGIN.getMsg(), ResultStatus.FAILOfficial);
        }
        //登录用户无分配校区
        if(loginUser.getCampusId() == null){
            throw new BusinessException(BaseError.ERROR_NO_CAMPUS.getMsg(), ResultStatus.FAILOfficial);
        }
        return customInfoMapper.queryFollowCustomerCount(loginUser.getCampusId());
    }

    //查询今日待跟进的学员列表
    @Override
    public List<CustomerListResDto> queryFollowCustomerList(){
        CustomerListReqDto reqDto = new CustomerListReqDto();
        reqDto.setNextCommunicateTimeStart(Util.ChangeDateToString(new Date(),DateUtil.dateFormat));
        reqDto.setNextCommunicateTimeEnd(Util.ChangeDateToString(new Date(),DateUtil.dateFormat));
        return queryCustomerInfoListByParam(reqDto);
    }

    //查询配置
    @Override
    public String queryPageListColumnsConfig(Integer configType){
        LoginUserDto loginUser = getCurrentUser();
        //未登录
        if(loginUser == null){
            throw new BusinessException(BaseError.ERROR_NO_LOGIN.getMsg(), ResultStatus.FAILOfficial);
        }
        return pageListColumnsConfigMapper.queryPageListColumnsConfig(configType,loginUser.getId());
    }

    //新增/修改配置
    @Override
    public boolean addOrUpdatePageListColumnsConfig(AddPageListColumnsConfigReqDto parmDto){
        LoginUserDto loginUser = getCurrentUser();
        //未登录
        if(loginUser == null){
            throw new BusinessException(BaseError.ERROR_NO_LOGIN.getMsg(), ResultStatus.FAILOfficial);
        }
        String configData = pageListColumnsConfigMapper.queryPageListColumnsConfig(parmDto.getConfigType(),loginUser.getId());
        PageListColumnsConfig entity = new PageListColumnsConfig();
        PropertiesUtil.copyProperties(parmDto,entity);
        entity.setUserId(loginUser.getId());
        if(StringUtils.isNotBlank(configData)){
            //存在，则修改
            return pageListColumnsConfigMapper.updatePageListColumnsConfigData(entity) > 0;
        } else {
            //不存在，则新增
            entity.setId(snowFlakeUtil.nextId());
            entity.setCreateBy(loginUser.getId());
            entity.setUpdateBy(loginUser.getId());
            entity.setCreateTime(new Date());
            entity.setUpdateTime(new Date());
            return pageListColumnsConfigMapper.addPageListColumnsConfig(entity) > 0;
        }
    }

    //根据校区查询用户信息
    @Override
    public List<AccountInfoListResDto> queryUserInfoListByCampusId(){
        LoginUserDto loginUser = getCurrentUser();
        //未登录
        if(loginUser == null){
            throw new BusinessException(BaseError.ERROR_NO_LOGIN.getMsg(), ResultStatus.FAILOfficial);
        }
        //登录用户无分配校区
        if(loginUser.getCampusId() == null){
            throw new BusinessException(BaseError.ERROR_NO_CAMPUS.getMsg(), ResultStatus.FAILOfficial);
        }
        List<AccountInfoListResDto> resDtoList =  permissionClient.queryUserInfoListByCampusId(getBearerToken(),loginUser.getId(),loginUser.getCampusId()).getData();
        AccountInfoListResDto resDto = new AccountInfoListResDto();
        resDto.setId(loginUser.getId());
        resDto.setTrueName(CrmConstant.USER_TRUE_NAME);
        resDtoList.add(0,resDto);
        return resDtoList;
    }

    //根据真实姓名模糊查询用户信息
    @Override
    public List<AccountInfoListResDto> queryUserInfoListByTrueName(String trueName){
        LoginUserDto loginUser = getCurrentUser();
        //未登录
        if(loginUser == null){
            throw new BusinessException(BaseError.ERROR_NO_LOGIN.getMsg(), ResultStatus.FAILOfficial);
        }
        //登录用户无分配校区
        if(loginUser.getCampusId() == null){
            throw new BusinessException(BaseError.ERROR_NO_CAMPUS.getMsg(), ResultStatus.FAILOfficial);
        }
        List<AccountInfoListResDto> resDtoList =  permissionClient.queryUserInfoListByTrueName(getBearerToken(),trueName,loginUser.getCampusId()).getData();
        return resDtoList;
    }

    public QueryResponse exportExcel(CustomerListReqDto reqDto) throws Exception {
        List<CustomerListResDto> customerList = queryCustomerInfoListByParam(reqDto);
        XSSFWorkbook workbook= ExcelUtil.createExcel(customerList,CustomerListResDto.class,null);
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        workbook.write(os);
        byte[] content = os.toByteArray();
        InputStream is = new ByteArrayInputStream(content);
        String filePathName=excelPath+clueExportFileName.substring(0,clueExportFileName.indexOf(".xls"))
                +DateUtil.ChangeDateToString(new Date(),DateUtil.dateFormat2)+clueExportFileName.substring(
                        clueExportFileName.indexOf(".xls"),clueExportFileName.length());
        boolean upload = uploadUtil.upload(is, filePathName);
        if (upload){
            CustomerExportDto customerExportDto=new CustomerExportDto();
            customerExportDto.setDownloadUrl(uploadUtil.getOSSUrl(filePathName,CrmConstant.CLUE_EXPORT_VALID_TIME));
            return QueryResponse.setResData(customerExportDto);
        }
        return new QueryResponse(ResultStatus.EXPORT_FILE_OSS_SERVER__ERROR);
    }

}
